合并两颗平衡有序二叉树

问题描述

给定两颗平衡的有序二叉树,要求将这两个二叉树合并为一个平衡的有序二叉树。

问题解答

假定两个数的结点数分别为m和n。

思路1

很容易想到把一颗树的每一个结点依次添加到另一颗树中,每次插入的平均时间复杂度为O(logn),在最坏情况下的插入时间复杂度为O(m + logn)。合并为一棵树的平均时间复杂度为O(mlog(m + n))。

单纯地将节点插入树中会破坏树的平衡性,因此之后需要将树展开为链表然后再生成平衡二叉树,时间复杂度为O(m + n)。

在插入过程中保持树的平衡性实现起来很困难,而且时间复杂度也会相应增加。

思路2:

考虑到结果二叉树是平衡的,因此将树展开然后生成平衡二叉树是无法避免的,因此可以考虑以下做法。

首先,将两棵树分别展开为有序链表,时间复杂度分别为O(m)和O(n);

    public TreeNode prev = null;
    public void BSTtoLinkedList(TreeNode root) {
        if (root == null) return;
        BSTtoLinkedList(root.left);
        if (prev != null) {
            prev.right = root;
            prev.left = null;
        }
        prev = root;
        BSTtoLinkedList(root.right);
    }

 

然后将两个有序链表合并,时间复杂度为O(m + n);

    public TreeNode MergeTwoLinkedList(TreeNode n1, TreeNode n2) {
        TreeNode head = new TreeNode();
        while (n1 != null && n2 != null) {
            if (n1.val < n2.val) {
                head.right = n1;
                n1 = n1.right;
            } else {
                head.right = n2;
                n2= n2.right;
            }
            head = head.right;
        }
        if (n1 != null) {
            head.right = n1;
            head = head.right;
        }
        if (n2 != null) {
            head.right = n2;
            head = head.right;
        }
        return head.right;
    }

 

最后把一个有序链表转化为一个平衡二叉树,时间复杂度为O(m + n)。

    public TreeNode LinkedListToBalancedBST(TreeNode root) {
        int num = 0;
        while (root != null) {
            num++;
            root = root.right;
        }
        return ListToBST(root, num);
    }
    public TreeNode cur = null;
    public TreeNode ListToBST(TreeNode root, int num) {
        if (num <= 0) return null;
        if (cur == null) cur = root;
        TreeNode left = ListToBST(root, num / 2);
        TreeNode temp = cur;
        cur = cur.right;
        temp.right = ListToBST(cur, num - 1 - num / 2);
        temp.left = left;
        return temp;
    }

 

posted on 2017-01-02 23:07  ShinningWu  阅读(5348)  评论(0编辑  收藏  举报

导航